package com.atguigu.crowd.handler;

import com.atguigu.crowd.api.MySQLRemoteService;
import com.atguigu.crowd.config.OSSProperties;
import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.po.MemberPO;
import com.atguigu.crowd.entity.vo.ProjectVO;
import com.atguigu.crowd.entity.vo.*;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.security.auth.message.AuthStatus;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

//创建众筹项目的所有consumer handler操作
@Controller
public class ProjectConsumerHandler{


	@Autowired
	private OSSProperties ossProperties;

	@Autowired
	private MySQLRemoteService mySQLRemoteService;

	//在发起众筹前进行判断 发起人是否已经实名认证 发起人项目开发失败次数 是否超过2次
	@RequestMapping("/agree/protocol/page")
	public String judgeAgreeCrowd(HttpSession session,ModelMap modelMap){

		MemberLoginVO loginMember = (MemberLoginVO)session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);


//		ResultEntity<MemberPO> memberPOByLoginAcctRemote = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginMember);
		//判断是否已经实名认证 没有 则跳转到实名认证页
		Integer authstatus = loginMember.getAuthstatus();
//		System.out.println("实名: "+authstatus);
		if(authstatus!=2){
			//没有实名认证完成
			modelMap.addAttribute("NoMemberAuth","不可发起项目 实名认证未完成 请完成实名认证");
//			session.setAttribute("NoMemberAuth","不可发起项目 实名认证未完成 请完成实名认证");
			return "fail-message";
		}
		//判断发起人项目开发失败次数 是否超过2次 超过 则跳转到不允许再发起页面 回到首页
		Integer failednum = loginMember.getFailedNum();
		if(failednum>=2){
			//不可再发起项目
			modelMap.addAttribute("FailedNum2","不可发起项目 项目开发次数已超过2次");
//			session.setAttribute("FailedNum2","不可发起项目 项目开发次数已超过2次");
			return "fail-message";
		}

		return "project-agree";
	}

	//更多项目 单机游戏页及其他页面
	@RequestMapping("/show/more/other")
	public String getMoreProjectSingle(ModelMap modelMap, HttpServletRequest request){

		Integer typeId = Integer.parseInt(request.getParameter("typeId"));
		ResultEntity<List<PortalProjectVO>> portalTypeProjectDataRemote = mySQLRemoteService.getMoreProjectOtherRemote(typeId);



		//2.检查查询结果
		if(ResultEntity.SUCCESS.equals(portalTypeProjectDataRemote.getResult())) {
			//3.拿到查询到的结果
			List<PortalProjectVO> data = portalTypeProjectDataRemote.getData();
			modelMap.addAttribute("more_project_other", data);

		}
		return "project-more-other";
	}



	//	更多项目页
	//全部项目 使用modelMap
	@RequestMapping("/show/more/all")
	public String getMoreProjectAll(ModelMap modelMap){

		ResultEntity<List<PortalProjectVO>> resultEntity = mySQLRemoteService.getMoreProjectAllRemote();

		//2.检查查询结果
		if(ResultEntity.SUCCESS.equals(resultEntity.getResult())) {
			//3.拿到查询到的结果
			List<PortalProjectVO> portalProjectVOS = resultEntity.getData();

			//4.存入request域 以便在首页进行填充
			modelMap.addAttribute(CrowdConstant.ATTR_NAME_MORE_PROJECT, portalProjectVOS);
		}
		return "project-more";
	}



	/**
	 * 获取项目详情页信息
	 * @param projectId
	 * @param modelMap
	 * @return
	 */
	@RequestMapping("/get/project/detail/{projectId}")
	public String getProjectDetail(
			@PathVariable("projectId") Integer projectId,
			ModelMap modelMap
	){
		ResultEntity<DetailProjectVO> resultEntity = mySQLRemoteService.getDetailProjectVORemote(projectId);
		if(ResultEntity.SUCCESS.equals(resultEntity.getResult())){
			DetailProjectVO projectVO = resultEntity.getData();
			//存入request域
			modelMap.addAttribute("detailProjectVO",projectVO);
		}
		return "project-show-detail";
	}


	/**
	 * 确认页 点击提交按钮 进行提交确认信息 将所有收集到的信息调用远程handler 保存到数据库
	 */
	@RequestMapping("/create/confirm")
	public String saveConfirm(
			ModelMap modelMap,
			HttpSession session,
			MemberConfirmInfoVO memberConfirmInfoVO
	){
		// 1.从Session域读取之前临时存储的ProjectVO对象
		ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);

//		System.out.println("proVO money: "+projectVO.getMoney());
		// 2.如果projectVO为null
		if(projectVO == null) {
			throw new RuntimeException(CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
		}

		// 3.将确认信息数据设置到projectVO对象中
		projectVO.setMemberConfirmInfoVO(memberConfirmInfoVO);

		// 4.从Session域读取当前登录的用户
		MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);

		Integer memberId = memberLoginVO.getId();





		// 5.调用远程方法保存projectVO对象
		ResultEntity<String> saveResultEntity = mySQLRemoteService.saveProjectVORemote(projectVO, memberId);

		// 6.判断远程的保存操作是否成功
		String result = saveResultEntity.getResult();
		if(ResultEntity.FAILED.equals(result)) {

			modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());

			return "project-confirm";
		}

		// 7.将临时的ProjectVO对象从Session域移除
		session.removeAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);

		// 8.如果远程保存成功则跳转到最终完成页面
		return "redirect:http://localhost:8888/project/create/success";


	}
	/**
	 * 回报页 点击确定 一个回报的全部信息 并进行提交
	 * 则下一步是只跳转页面即可
	 *
	 */
	@ResponseBody
	@RequestMapping("/create/save/return.json")
	public ResultEntity<String> saveReturn(
			ReturnVO returnVO,
			HttpSession session){


		try {
			//回报不能为空
//			if(returnVO ==null){
//				return "project-return";
//			}
			// 1.从session域中读取之前缓存的ProjectVO对象
			ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);

			// 2.判断projectVO是否为null
			if(projectVO == null) {
				return ResultEntity.failed(CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
			}

			// 3.从projectVO对象中获取存储回报信息的集合
			List<ReturnVO> returnVOList = projectVO.getReturnVOList();

			// 4.判断returnVOList集合是否有效
			if(returnVOList == null || returnVOList.size() == 0) {

				// 5.创建集合对象对returnVOList进行初始化
				returnVOList = new ArrayList<>();
				// 6.为了让以后能够正常使用这个集合，设置到projectVO对象中
				projectVO.setReturnVOList(returnVOList);
			}

			// 7.将收集了表单数据的returnVO对象存入集合
			returnVOList.add(returnVO);

			// 8.把数据有变化的ProjectVO对象重新存入Session域，以确保新的数据最终能够存入Redis
			session.setAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);

			// 9.所有操作成功完成返回成功
			return ResultEntity.successWithoutData();
		} catch (Exception e) {
			e.printStackTrace();

			return ResultEntity.failed(e.getMessage());
		}


	}

	/**
	 * 回报页
	 * 上传图片 接收图片 上传到OSS 并返回图片路径
	 * ajax请求
	 * 因为这里是先单独上传图片 不是随表单提交 所有使用ajax请求
	 * 图片过大 则会失败
	 */
	// JavaScript代码：formData.append("returnPicture", file);
	// returnPicture是请求参数的名字
	// file是请求参数的值，也就是要上传的文件
	/*
	$.ajax({
			"url":"[[@{/project/create/upload/return/picture.json}]]",
			"type":"post",
			"data":formData,
	 */
	@ResponseBody
	@RequestMapping("/create/upload/return/picture.json")
	public ResultEntity<String> uploadReturnPicture(
			// 接收用户上传的文件
			@RequestParam("returnPicture") //这个注解不加也可以
					MultipartFile returnPicture
	) throws IOException {

		//1.执行文件 图片上传
		ResultEntity<String> uploadReturnPicResultEntity = CrowdUtil.uploadFileToOss(
				ossProperties.getEndPoint(),
				ossProperties.getAccessKeyId(),
				ossProperties.getAccessKeySecret(),
				returnPicture.getInputStream(),
				ossProperties.getBucketName(),
				ossProperties.getBucketDomain(),
				returnPicture.getOriginalFilename());

		//2.返回上传结果
		return uploadReturnPicResultEntity;
	}

	/**
	 * 接收来自项目及发起人信息页的数据
	 * 其中主要做的是图片上传 以及将图片路径填充进ProjectVO
	 * 其他信息已经通过表单提交 参数绑定了
	 * @return
	 */
	@RequestMapping("/create/project/information")
	public String saveProjectBasicInfo(
			// 接收除了上传图片之外的其他普通数据
			ProjectVO projectVO,

			// 接收上传的头图
			MultipartFile headerPicture,

			// 接收上传的详情图片
			List<MultipartFile> detailPictureList,

			// 用来将收集了一部分数据的ProjectVO对象存入Session域
			HttpSession session,

			// 用来在当前操作失败后返回上一个表单页面时携带提示消息
			ModelMap modelMap
	) throws IOException {

		//检查此用户的发起人信息是否已经存在 如果已经存在 只能修改 不再新加
		MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);

		Integer memberId = memberLoginVO.getId();

		ResultEntity<Boolean> resultEntity = mySQLRemoteService.getInfoByMemberIdFromLaunch(memberId);
		Boolean HaveLaunch = resultEntity.getData();
		if (HaveLaunch){
			//已经有发起人信息了 可以改
			session.setAttribute("LaunchMessage","已有发起人信息,当前填写默认为修改");
			session.setAttribute("LaunchHave","true");
		}

		//设置开发周期
		projectVO.setDevelopment_day(projectVO.getPlanDay1()+projectVO.getPlanDay2()+projectVO.getPlanDay3()+projectVO.getPlanDay4()+5);

		//1.完成头图上传
		boolean headerPictureIsEmpty = headerPicture.isEmpty();

		if(headerPictureIsEmpty){
			//没有头图 则返回到表单页面并显示错误消息
			modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_EMPTY);
			return "project-launch";
		}
		//不是空的 上传
		ResultEntity<String> uploadHeaderPicResultEntity = CrowdUtil.uploadFileToOss(
				ossProperties.getEndPoint(),
				ossProperties.getAccessKeyId(),
				ossProperties.getAccessKeySecret(),
				headerPicture.getInputStream(),
				ossProperties.getBucketName(),
				ossProperties.getBucketDomain(),
				headerPicture.getOriginalFilename());

		//判断头图是否上传成功
		if(ResultEntity.SUCCESS.equals(uploadHeaderPicResultEntity.getResult())){
			//成功 则从返回的数据中获取图片访问路径
			String headerPicturePath = uploadHeaderPicResultEntity.getData();

			// 6.存入ProjectVO对象中
			projectVO.setHeaderPicturePath(headerPicturePath);
		}else {
			// 7.如果上传失败则返回到表单页面并显示错误消息
			modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_UPLOAD_FAILED);

			return "project-launch";
		}



		//详情图片上传 详情图片可能有多张 需要遍历集合
		// 1.创建一个用来存放详情图片路径的集合
		List<String> detailPicturePathList = new ArrayList<String>();

		// 2.检查detailPictureList是否有效
		if(detailPictureList == null || detailPictureList.size() == 0) {
			modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);

			return "project-launch";
		}

		// 3.遍历detailPictureList集合
		for (MultipartFile detailPicture : detailPictureList) {

			// 4.当前detailPicture是否为空
			if(detailPicture.isEmpty()) {
				//有一个上传失败就返回
				// 5.检测到详情图片中单个文件为空也是回去显示错误消息
				// 就是有文件但是字节数为0 isEmpty返回true
			//	boolean isEmpty()返回上传的文件是否为空，也就是说，在多部分格式中没有选择文件，或者选择的文件没有内容。
				modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);

				return "project-launch";
			}

			// 6.执行上传
			ResultEntity<String> detailUploadResultEntity = CrowdUtil.uploadFileToOss(
					ossProperties.getEndPoint(),
					ossProperties.getAccessKeyId(),
					ossProperties.getAccessKeySecret(),
					detailPicture.getInputStream(),
					ossProperties.getBucketName(),
					ossProperties.getBucketDomain(),
					detailPicture.getOriginalFilename());

			// 7.检查上传结果
			String detailUploadResult = detailUploadResultEntity.getResult();

			if(ResultEntity.SUCCESS.equals(detailUploadResult)) {

				String detailPicturePath = detailUploadResultEntity.getData();

				// 8.收集刚刚上传的图片的访问路径
				detailPicturePathList.add(detailPicturePath);
			} else {

				// 9.如果上传失败则返回到表单页面并显示错误消息
				modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_UPLOAD_FAILED);

				return "project-launch";
			}
		}
		// 10.将存放了详情图片访问路径的集合存入ProjectVO中
		projectVO.setDetailPicturePathList(detailPicturePathList);

		// 三、后续操作
		// 1.将ProjectVO对象存入Session域
		session.setAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);

		// 2.以完整的访问路径前往下一个收集回报信息的页面
		return "redirect:http://localhost:8888/project/return/info/page";
		//试试下面的路径
//		return "redirect:/project/return/info/page";
	}

}